QuickOPC User's Guide and Reference
Examples - OPC Unified Architecture - Subscribe to multiple nodes and keep state in dictionary
// This example shows how to store current state of the subscribed monitored items in a dictionary.
// each change.

using System;
using System.Collections.Generic;
using System.Threading;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples._EasyUAClient
{
    partial class SubscribeMultipleMonitoredItems
    {
        public static void StoreInDictionary()
        {
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            // Instantiate the client object and hook events.
            using (var client = new EasyUAClient())
            {
                client.DataChangeNotification += client_DataChangeNotification_StoreInDictionary;

                Console.WriteLine("Subscribing...");
                client.SubscribeMultipleMonitoredItems(new[]
                {
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor,
                        "nsu=http://test.org/UA/Data/ ;i=10845", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor,
                        "nsu=http://test.org/UA/Data/ ;i=10853", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor,
                        "nsu=http://test.org/UA/Data/ ;i=10855", 1000)
                });

                Console.WriteLine("Processing monitored item changed events for 1 minute...");
                int startTickCount = Environment.TickCount;
                do
                {
                    Thread.Sleep(5 * 1000);

                    // Each 5 seconds, display the current state of the monitored items we have subscribed to.
                    lock (_serialize)
                    {
                        Console.WriteLine();
                        foreach (KeyValuePair<UANodeDescriptor, UAAttributeDataResult> pair in _attributeDataResultDictionary)
                        {
                            UANodeDescriptor nodeDescriptor = pair.Key;
                            UAAttributeDataResult attributeDataResult = pair.Value;
                            Console.WriteLine($"{nodeDescriptor}: {attributeDataResult}");
                        }

                        // The code above shows how you can process the complete contents of the dictionary. In other
                        // scenarios, you may want to access just a specific entry in the dictionary. You can achieve that
                        // by indexing the dictionary by the node descriptor of the monitored item you are interested in.
                    }
                } while (Environment.TickCount < startTickCount + 60 * 1000);

                Console.WriteLine("Unsubscribing...");
            }

            Console.WriteLine("Finished.");
        }

        static void client_DataChangeNotification_StoreInDictionary(object sender, EasyUADataChangeNotificationEventArgs e)
        {
            lock (_serialize)
                // Convert the event arguments to a UAAttributeData result object, and store it in the dictionary under the
                // key which is the node descriptor of the monitored item this data change notification is for.
                _attributeDataResultDictionary[e.Arguments.NodeDescriptor] = (UAAttributeDataResult)e;
        }

        // Holds last known state of each subscribed monitored item.
        private static readonly Dictionary<UANodeDescriptor, UAAttributeDataResult> _attributeDataResultDictionary =
            new Dictionary<UANodeDescriptor, UAAttributeDataResult>();

        // Synchronization object used to prevent simultaneous access to the dictionary.
        private static readonly object _serialize = new object();
    }
}
# This example shows how to store current state of the subscribed monitored items in a dictionary.
# each change.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import threading
import time

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *


lock = threading.Lock()
attributeDataResultDictionary = {}

# Data change notification event handler.
def dataChangeNotification(sender, eventArgs):
    global lock
    global attributeDataResultDictionary
    with lock:
        # Convert the event arguments to a UAAttributeData result object, and store it in the dictionary under the
        # key which is the node descriptor of the monitored item this data change notification is for.
        attributeDataResultDictionary[eventArgs.Arguments.NodeDescriptor] = EasyUADataChangeNotificationEventArgs.ToUAAttributeDataResult(eventArgs)


endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer')
# or 'http://opcua.demo-this.com:51211/UA/SampleServer' (currently not supported)
# or 'https://opcua.demo-this.com:51212/UA/SampleServer/'

# Instantiate the client object.
client = EasyUAClient()
# Hook events.
client.DataChangeNotification += dataChangeNotification

print('Subscribing...')
client.SubscribeMultipleMonitoredItems([
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855'),
        UAMonitoringParameters(1000)),
    ])

print('Processing data change events for 1 minute...')
endTime = time.time() + 60
while time.time() < endTime:
    time.sleep(5)
    #
    # Each 5 seconds, display the current state of the monitored items we have subscribed to.
    with lock:
        print()
        print('Current state of the monitored items:')
        for nodeDescriptor, attributeDataResult in attributeDataResultDictionary.items():
            print(nodeDescriptor, ': ', attributeDataResult, sep='')
        #
        # The code above shows how you can process the complete contents of the dictionary. In other
        # scenarios, you may want to access just a specific entry in the dictionary. You can achieve that
        # by indexing the dictionary by the node descriptor of the monitored item you are interested in.

print()
print('Unsubscribing all monitored items...')
client.UnsubscribeAllMonitoredItems()

print('Waiting for 5 seconds...')
time.sleep(5)

print('Finished.')

 

See Also

Conceptual

Examples - OPC UA Alarms&Conditions

Examples - OPC Data Access

Examples - OPC UA Specialized